require 'yaml'

# Requires an apps.yml file in this directory formatted like:
#
#   foo:
#     root: /users/home/bob/projects/:app
#     tmp: :root/tmp
#     env: production
#     processes: 1
#
# The values shown above for tmp, env, and processes are the default values, so you can leave them out
# if you wish.
#
# Here are the available commands:
# 
#   # spawn all configured apps
#   rake spawn_all
#
#   # spawn specific app
#   rake spawn APP=foo 
#
#   # output snippet of lighttpd command, because admit it, you're lazy like me.
#   rake lighttpd APP=foo

desc 'spawns all apps'
task :spawn_all => :config do
  APPS.keys.each do |app|
    ENV['APP'] = app
    Rake::Task[:spawn].execute
  end
end

desc 'loads app.yml file'
task :config do
  return if Object.const_defined? :APPS
  APPS = YAML.load_file 'apps.yml'
  APPS.each do |app, conf|
    APPS[app]['root']      = conf['root'].gsub /:app/, app
    APPS[app]['tmp']       = (conf['tmp'] || ':root/tmp').gsub /:root/, APPS[app]['root']
    APPS[app]['env']       = conf['env'] || 'production'
    APPS[app]['processes'] = conf['processes'].nil? ? 1 : conf['processes'].to_i
  end
end

desc 'spawns a single application'
task :spawn do
  Rake::Task[:config].invoke unless Object.const_defined? :APPS
  raise "requires APP var to set specific app to spawn" unless ENV['APP']
  conf = APPS[ENV['APP']]
  raise "invalid app #{ENV['APP']}" unless conf
  puts "Starting #{conf['processes']} process(es) for #{ENV['APP']}"
  rm_rf   conf['tmp']
  mkdir_p conf['tmp']
  conf['processes'].times do |i|
    system "spawn-fcgi -f #{conf['root']}/public/dispatch.fcgi -s #{conf['tmp']}/#{ENV['APP']}-#{i}.socket -P #{conf['tmp']}/#{ENV['APP']}-#{i}.pid RAILS_ENV=#{conf['env']}"
  end
end

desc 'shows lighttpd config'
task :lighttpd => :config do
  raise "requires APP var to set specific app to spawn" unless ENV['APP']
  conf = APPS[ENV['APP']]
  raise "invalid app #{ENV['APP']}" unless conf

  lighty_conf = (0..(conf['processes'] - 1)).to_a.collect do |i|
    %(( "socket" => "#{conf['tmp']}/#{ENV['APP']}-#{i}.socket" ))
  end.join(",\n")
  puts lighty_conf
end